﻿using System;
using Microsoft.Extensions.DependencyInjection;

namespace 依然注入
{
    internal class Program
    {

        static void Main(string[] args)
        {
            // 面向接口
            ServiceCollection services = new ServiceCollection();
            services.AddScoped<ID服务注册, TestServiceImpl>();
            services.AddScoped<ID服务注册, TestServiceImpl2>();
            // services.AddScoped(typeof(ID服务注册),typeof(TestServiceImpl));
            // services.AddSingleton<ID服务注册, TestServiceImpl>();
            // services.AddSingleton(typeof(ID服务注册), new TestServiceImpl());  //可以通过new先传个参数
            using (ServiceProvider sp = services.BuildServiceProvider())
            {
                // ************************************************************
                // 返回单个服务
                /*
                ID服务注册 ts1 = sp.GetService<ID服务注册>();  // 如果找不到服务，就返回null
                ts1.Name = "111";
                ts1.SayHai();
                Console.WriteLine(ts1.GetType());
                */
                // ************************************************************


                // ************************************************************
                // 返回多个服务
                /*
                var ts1 = sp.GetServices<ID服务注册>();
                foreach (ID服务注册 t in ts1)
                {
                    Console.WriteLine(t.GetType());
                }
                */
                // ************************************************************

                // ************************************************************
                // 如果多个服务，就要最后一个
                var t = sp.GetRequiredService<ID服务注册>();
                Console.WriteLine(t);
                // ************************************************************

                // GetRequiredService 必须有服务  ,没有服务，就抛出异常
                // GetServices 没有服务  返回null

            }

            Console.ReadLine();
        }
        static void Main1(string[] args)
        {
            // 服务定位

            // 依赖注入
            // 1.下载 Microsoft.Extensions.DependencyInjection
            // 2、using Microsoft.Extensions.DependencyInjection;
            
            ServiceCollection services = new ServiceCollection(); //构造容器对象
            // services.AddTransient<TestServiceImpl>(); // 添加瞬态服务
            // services.AddSingleton<TestServiceImpl>(); // 单例
            services.AddScoped<TestServiceImpl>(); // 范围
            using (ServiceProvider sp = services.BuildServiceProvider()) // 服务定位器
            {
                //TestServiceImpl t1 = sp.GetService<TestServiceImpl>(); // 获取服务
                //t1.Name = "tom";
                //t1.SayHai();

                //TestServiceImpl t2 = sp.GetService<TestServiceImpl>();
                //Console.WriteLine($"是否是同个生命周期：" + object.ReferenceEquals(t1, t2));

                // scope 中获取相关对象
                TestServiceImpl tt1;
                using (IServiceScope scope1 = sp.CreateScope())
                {
                    TestServiceImpl t1 = scope1.ServiceProvider.GetService<TestServiceImpl>();
                    t1.Name = "Tom";
                    t1.SayHai();
                    TestServiceImpl t2 = scope1.ServiceProvider.GetService<TestServiceImpl>();
                    t2.Name = "aggie";
                    t2.SayHai();
                    Console.WriteLine($"是否是同个生命周期：" + object.ReferenceEquals(t1, t2));
                    tt1 = t1;
                }
                using (IServiceScope scope2 = sp.CreateScope())
                {
                    TestServiceImpl t1 = scope2.ServiceProvider.GetService<TestServiceImpl>();
                    t1.Name = "Tom";
                    t1.SayHai();
                    TestServiceImpl t2 = scope2.ServiceProvider.GetService<TestServiceImpl>();
                    t2.Name = "aggie";
                    t2.SayHai();
                    Console.WriteLine($"是否是同个生命周期：" + object.ReferenceEquals(t1, t2));
                    Console.WriteLine($"二个不同范围的是否同个对象：" + object.ReferenceEquals(tt1, t2));
                }

            }

            // 生命周期
            // services.AddTransient<TestServiceImpl>(); // 添加瞬态服务 每次获取服务都是不同对象
            // services.AddSingleton<TestServiceImpl>(); // 单例服务  拿到的是同个对象
            // services.AddScoped<TestServiceImpl>(); // 范围 同个线程下，都是同个对象
        }
    }
}
